到目前為止所跑的測試都是利用 docker 在本機run scylla & redis 測試的,
今天利用Go interface
來把model的程式改成不需要依賴外部回應的方式。
Go
有兩種interface
, 一個是資料型別, 一個是定義接口。
資料型別的interface 會像這樣使用:
// 宣告參數 interface{}
var data interface{}
// 傳入參數 interface{}
func Test(i interface{}) (r string) {}
// 回傳參數 interface{}
func Test(i string) (r interface{}) {}
``
就跟`int`, `string`, `bool`一樣, 用來表示資料的型態。
定義接口的interface 會是這樣使用:
ype ITest interface{
Create(seq int, data string) error
Update(t *Test) error
``
在Go裡面只要有一個 struct 滿足 `Create()` 和 `Update()`兩個接口條件,
就可以透過將變數宣告為 ITest 來調用不同struct底下的接口。
這個特性可以用在本機測試, 如果已知對接的接口或API回應格式, 就可以實作mock的API接口來測試。
修改model底下的程式, 調整為interface接口
model
├── init.go
└── limit.go
實作內容
package coconut_model
import (
"github.com/syhlion/gocql"
)
// Init
func Init(cql *gocql.Session) {
LimitSQL = &RealModel{
cqlDB: cql,
}
}
// InitMock
func InitMock() {
LimitSQL = &MockModel{}
}
type IModel interface {
GetLimit() (result map[string]int, err error)
}
var LimitSQL IModel
type RealModel struct {
cqlDB *gocql.Session
}
func (r *RealModel) GetLimit() (result map[string]int, err error) {
var (
level string
limit int
)
result = make(map[string]int)
sql := `select level, limit_point from coconut.settings`
iter := r.cqlDB.Query(sql).Iter()
for iter.Scan(&level, &limit) {
result[level] = limit
}
if err := iter.Close(); err != nil {
return nil, err
}
return
}
type MockModel struct{}
func (m *MockModel) GetLimit() (result map[string]int, err error) {
result = make(map[string]int, 0)
result["0"] = 11111
result["1"] = 2222
result["2"] = 333
result["3"] = 55
return result, nil
}
在config中加入一個參數config.Environment
決定要不要跑mock的環境
if config.Environment == "local" {
coconut_model.InitMock()
} else {
coconut_model.Init(session)
}
調整 rpc.go
limitSettings, err := coconut_model.LimitSQL.GetLimit()
Mock 在以前使用 Http API的時候比較能明顯感受到它的便利性, 只要API格式確認之後就可以Mock出來開發,後來使用gRPC服務之後就有spec可以參考了, 所以目前比較常用來Mock的是對資料庫或redis取資料的回應狀況。